#pragma once


// mysql版本
#include <unordered_map>
#include <vector>
#include <string>
#include <fstream>
#include <algorithm>
#include <cassert>

#include "../comm/util.hpp"
#include "../comm/log.hpp"
#include "mysql/mysql.h"

//model 主要负责处理与数据的交互，比如增删改查
namespace ns_model
{
    using namespace std;
    using namespace ns_util;
    using namespace ns_log;
    //描述题目结构体
    struct Question{
        string number; //题目标号
        string title;  //题目标题
        string grade; //分为简单 中等 困难
        int cpu_limit; //时间限制
        int mem_limit; //空间限制
        string desc; //具体描述
        string header; //提供给用户的预设代码
        string tail;  //测试用例，最后拼接用户代码，形成完整代码代码
    };

    const string oj_questions = "oj_questions";
    const string host = "127.0.0.1";
    const string user = "oj_c";
    const string passwd = "123456";
    const string db = "oj";
    int port = 3306;

    class Model
    {
        public:
        Model()
        {
        }
        bool QueryMySql(const string &sql, vector<Question> *out)
        {
            //创建句柄
            MYSQL *my = mysql_init(nullptr);    

            //链接数据库
            if(mysql_real_connect(
                my, 
                host.c_str(), 
                user.c_str(),
                passwd.c_str(), 
                db.c_str(),
                port, nullptr,
                0
            ) == nullptr)
            {   
                LOG(FATAL) << "连接数据库失败！" << endl;
                return false;
            }
            
            //链接数据库成功以后一定要设置连接的编码格式,解决乱码问题
            mysql_set_character_set(my, "utf8");

            //执行sql语句
            if(mysql_query(my, sql.c_str()) != 0)
            {
                LOG(WARNING) << sql << "  execute error!" << endl;
                return false;
            }


            //获取结果集
            MYSQL_RES * res = mysql_store_result(my);

            //获取rows and cols ,分析结果
            int rows = mysql_num_rows(res);
            int cols = mysql_num_fields(res);


            for(int i = 0; i < rows; i++)
            {
                Question q;
                MYSQL_ROW row = mysql_fetch_row(res);
                q.number = row[0];
                q.title = row[1];
                q.grade = row[2];
                q.desc = row[3];
                q.header = row[4];
                q.tail = row[5];
                q.cpu_limit = atoi(row[6]);
                q.mem_limit = atoi(row[7]);

                out->push_back(q);
            }


            //释放空间
            free(res);
            //关闭连接
            mysql_close(my);

            return true;
        }
        //查看题目列表
        bool GetAllQuestions(vector<Question> *out) 
        {
            string sql = "select * from ";
            sql += oj_questions;
            
            return QueryMySql(sql, out);
        }
        //查看指定题目
        bool GetOneQuestion(string number, Question *q)
        {
            bool ret = false;
            string sql = "select * from ";
            sql += oj_questions;
            sql += " where number=" + number;
            vector<Question> result;
            if(QueryMySql(sql, &result))
            {
                if(result.size() == 1)
                {
                    *q = result[0];
                    ret = true;
                }
            }
            return ret;
        }
        ~Model()
        {}
    };
}